package org.openzip.jarsfx.unpacking.view;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
 * This class loads jar entries from directory "data" in jar file and transforms
 * them into MyJarFile structure inherited from File class. This allows
 * unpacking gui to load jar entries as it was Files. That is in the same
 * fashion as it was used in archiving gui.
 * 
 * @author David �unek
 * 
 */
public class JarFileAdapter extends File {
	private List<JarEntry> entries = new ArrayList<JarEntry>();
	private MyJarFile rootDir;

	/**
	 * Constructor calls function loadFiles() which loads jar entries and
	 * converts them into structured Files.
	 */
	public JarFileAdapter() {
		super(System.getProperty("user.dir"));
		loadFiles();
	}

	/**
	 * The name of this File is currently "root"
	 */
	public String getName() {
		return "root";
	}

	/**
	 * This function returns Files in fully structured manner. That is every
	 * file contains its subdirectories and files.
	 */
	public File[] listFiles() {
		return rootDir.listFiles();
	}

	/**
	 * This function loads jar entries and sorts them in order to be recursively
	 * load by function loadFiles(MyJarFile dir). Function also converts jar
	 * entries into Files which can be returned by function listFiles() in fully
	 * structured manner. That is every file contains its subdirectories and
	 * files.
	 */
	private void loadFiles() {
		String jarFileName; /* = getClass().getProtectionDomain().getCodeSource()
				.getLocation().getFile();*/

		// TODO tento radek odstranit pokud to chci testovat na skutecnem jaru
		jarFileName = "C:\\Users\\Jakub\\Desktop\\abc.jar";

		JarFile jarFile = null;
		try {
			jarFile = new JarFile(jarFileName);
		} catch (IOException e) {
			e.printStackTrace();
		}

		// convertion from Enumeration to List
		Enumeration<JarEntry> jarEntries = jarFile.entries();
		while (jarEntries.hasMoreElements()) {
			JarEntry next = jarEntries.nextElement();
			System.out.println(next.getName());
			if (next.getName().startsWith("data")) {
				System.out.println("Jar Entry: " + next.getName());
				entries.add(next);
			}
		}
		// sort entries
		Collections.sort(entries, new JarEntryComparator());
		printEntries();

		// recursively load jar entries
		rootDir = new MyJarFile(entries.get(0));
		loadFiles(rootDir);
	}

	/**
	 * This function is called from loadFiles() function with "data" directory
	 * as a root. This function creates structure of files because it
	 * recursively calls itself. This structure can be obtained by calling
	 * listFiles() function.
	 * 
	 * @param Directory into which files are to be added.
	 */
	private int i = 0;

	private void loadFiles(MyJarFile dir) {
		while (entries.size() - 1 > i) {

			if (!entries.get(i + 1).getName().startsWith(dir.getEntryPath())) {
				break;
			}
			JarEntry jarEntry = entries.get(++i);
			MyJarFile jarFile = new MyJarFile(jarEntry);
			dir.addJarFile(jarFile);

			System.out.println("Adding " + jarFile.getName() + " to "
					+ dir.getName());

			if (jarEntry.isDirectory()) {
				loadFiles(jarFile);
			}

		}
	}

	// print sorted entries
	private void printEntries() {
		for (JarEntry jarEntry : entries) {
			if (jarEntry.getName().startsWith("data/")) {
				System.out.println("List: " + jarEntry.getName());
			}
		}
	}

	// comparator for entries
	private class JarEntryComparator implements Comparator<JarEntry> {
		@Override
		public int compare(JarEntry o1, JarEntry o2) {
			String s1 = o1.getName();
			String s2 = o2.getName();
			return s1.compareTo(s2);

		}
	}

}
